package com.lb.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.github.pagehelper.util.StringUtil;

import java.io.IOException;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

/**
 * @author user
 */
public class JsonUnderLineConvertUtils {
    private static final char UNDERLINE = '_';

    /**
     * 将对象的大写转换为下划线加小写，例如：userName-->user_name
     * 支持java bean及map对象
     *
     * @param object
     * @return
     * @throws JsonProcessingException
     */
    public static String toUnderlineStringByObject(Object object) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String reqJson = mapper.writeValueAsString(object);
        //Map 类型单独处理key 转换
        if (object.getClass().getName().equals(Map.class.getName()) || object.getClass().getName().equals(HashMap.class.getName())) {
            Map<String, Object> treeMap = new TreeMap<String, Object>(
                    new Comparator<String>() {
                        public int compare(String obj1, String obj2) {
                            // 降序排序
                            if (false) {
                                return obj1.compareTo(obj2);
                            } else { //升序
                                return obj2.compareTo(obj1);
                            }
                        }
                    });
            Map<String, Object> map = (Map) object;
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                treeMap.put(camelToUnderline(key), value);

            }
            reqJson = mapper.writeValueAsString(treeMap);
        }
        return reqJson;
    }

    /**
     * 将对象的大写转换为下划线加小写的Map对象，例如：userName-->user_name
     * 支持java bean及map对象
     *
     * @param object
     * @return jsonObject
     * @throws JsonProcessingException
     */
    public static Map<String, Object> toUnderlineMapByObject(Object object) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String reqJson = mapper.writeValueAsString(object);
        //Map 类型单独处理key 转换
        if (object.getClass().getName().equals(Map.class.getName()) || object.getClass().getName().equals(HashMap.class.getName())) {
            Map<String, Object> treeMap = new TreeMap<String, Object>(
                    new Comparator<String>() {
                        public int compare(String obj1, String obj2) {
                            // 降序排序
                            if (false) {
                                return obj1.compareTo(obj2);
                            } else { //升序
                                return obj2.compareTo(obj1);
                            }
                        }
                    });
            Map<String, Object> map = (Map) object;
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                treeMap.put(camelToUnderline(key), value);

            }
            reqJson = mapper.writeValueAsString(treeMap);
        }

        JSONObject jsonObject = JSON.parseObject(reqJson);
        return jsonObject;
    }

    /**
     * 将对象的大写转换为下划线加小写的Map对象，例如：userName-->user_name
     * 支持java bean及map对象
     *
     * @param object
     * @return jsonObject
     * @throws JsonProcessingException
     */
    public static <T> T toUnderlineObjectByObject(Object object, Class<T> clazz) throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        String reqJson = mapper.writeValueAsString(object);
        //Map 类型单独处理key 转换
        if (object.getClass().getName().equals(Map.class.getName()) || object.getClass().getName().equals(HashMap.class.getName())) {
            Map<String, Object> treeMap = new TreeMap<String, Object>(
                    new Comparator<String>() {
                        public int compare(String obj1, String obj2) {
                            // 降序排序
                            if (false) {
                                return obj1.compareTo(obj2);
                            } else { //升序
                                return obj2.compareTo(obj1);
                            }
                        }
                    });
            Map<String, Object> map = (Map) object;
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                String key = entry.getKey();
                Object value = entry.getValue();
                treeMap.put(camelToUnderline(key), value);

            }
            reqJson = mapper.writeValueAsString(treeMap);
        }

        return JSON.parseObject(reqJson, clazz);
    }

    /**
     * 将下划线JSON字符串转换为驼峰的形式，例如：user_name-->userName
     * 统一处理为Map再转换，支持Class java bean及map对象json对象字符串
     *
     * @param json
     * @param clazz 返回类型限制
     * @return
     * @throws IOException
     */
    public static <T> T toObject(String json, Class<T> clazz) throws IOException {
        //Map 类型单独处理key 转换
        Map<String, Object> treeMap = new TreeMap<String, Object>(
                new Comparator<String>() {
                    public int compare(String obj1, String obj2) {
                        // 降序排序
                        if (false) {
                            return obj1.compareTo(obj2);
                        } else { //升序
                            return obj2.compareTo(obj1);
                        }
                    }
                });
        Map<String, Object> map = JSON.parseObject(json);
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            treeMap.put(underlineToCamel(key), value);
        }
        return JSON.parseObject(JSON.toJSONString(treeMap), clazz);
    }

    /**
     * 将下划线属性bean转换为驼峰的形式的对象，例如：user_name-->userName
     *
     * @param lineBean 支持Class java bean及map对象
     * @param clazz 转换返回的类型
     * @return
     * @throws IOException
     */
    public static <T> T toObjectByLineBean(Object lineBean, Class<T> clazz) throws IOException {
        if(!lineBean.getClass().getName().equals(Map.class.getName()) &&! lineBean.getClass().getName().equals(HashMap.class.getName())){
            ObjectMapper mapper = new ObjectMapper();
            mapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
            mapper.setSerializationInclusion(Include.NON_NULL);
            String reqJson = mapper.writeValueAsString(lineBean);
            return JSON.parseObject(reqJson,clazz);
        }else{
            String json = JSON.toJSONString(lineBean);
            return toObject(json, clazz);
        }
    }

    /**
     * 将下划线对象转换为驼峰属性Map对象，例如：user_name-->userName
     *
     * @param object
     * @return
     * @throws IOException
     */
    public static Map<String, Object> toObjectMapByLineBean(Object lineObject) throws IOException {
        String json = JSON.toJSONString(lineObject);
        return toObject(json, Map.class);
    }


    /**
     * @param param
     * @return java.lang.String
     * @Description 属性名 驼峰转下划线
     * @Author jiaojing
     * @Date 2021/1/9 5:08 下午
     */
    public static String camelToUnderline(String param) {
        if (StringUtil.isEmpty(param)) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        int len = param.length();
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (Character.isUpperCase(c)) {
                sb.append(UNDERLINE);
                sb.append(Character.toLowerCase(c));
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }

    /**
     * @param param
     * @return java.lang.String
     * @Description 属性名 下划线转驼峰
     * @Author jiaojing
     * @Date 2021/1/9 5:09 下午
     */
    public static String underlineToCamel(String param) {
        if (StringUtil.isEmpty(param)) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        int len = param.length();
        for (int i = 0; i < len; i++) {
            char c = param.charAt(i);
            if (c == UNDERLINE) {
                if (++i < len) {
                    sb.append(Character.toUpperCase(param.charAt(i)));
                }
            } else {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}